#!/bin/bash

#----------------------------MGS Burner------------------------------
#Una solución de grabación, construída en BASH con interfaz GTK3.
#--------------------------------------------------------------------
#
#Copyright (C) 2013  Matías Gastón Santiago.
#Contact: <matiasbatero.mdq@gmail.com>

#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.

#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.

#You should have received a copy of the GNU General Public License
#along with this program.  If not, see <http://www.gnu.org/licenses/>

#--------------------------------------------------------------------

#Dependencias: cdrdao, dvd+rw-tools, pv, zenity
#Este script corre únicamente en BASH. Por eso, no cambie el encabezamiento del script. 
#Recuerde añadir permisos de ejecución para poder lanzar este script.
#Si su SHELL por defecto no es BASH. Procure armar un lanzador con las siguientes líneas:
#
#  #!/bin/sh
#  bash MGSBurner_ES.sh
#
#Guárdelo en un archivo al lado de este script, otórguele permisos de ejecución y ejecútelo.
#

#VERSION 1.02 23/12/2013

#Añadido pv como dependencia
#Se añadió el soporte de pendrives USB

#----------------------------------------------------------------------

#VERSION 1.01 22/12/2013

#Se añadió control de dependencias
#--------------------------------------------------------------------


dialog(){

case $1 in

'--mainlist')
devices(){
(cdrdao scanbus 2>&1 | sed 1d | sed 's/ //g' | sed 's/\:/ \: /g' | sed 's/\,/ /g') | while read line ;do echo "$line" ;done

find /dev/sd*  | while read line; do

vendor=`udevadm info --query=property --name=$line | grep -E 'ID_VENDOR' | sed 3d | sed 2d | sed 's/ID_VENDOR=//g'`
id=`udevadm info --query=property --name="$line" | grep ID_BUS | sed 's/ID_BUS=//g'`
capacity=`lsblk "$line" | grep disk | awk '{ print $4}'`
model=`udevadm info --query=property --name=$line | grep -E 'ID_MODEL' | sed 3d | sed 2d | sed 's/ID_MODEL=//g' | sed 's/_/ /g'`
sys=`lsblk $line | grep disk | awk '{print $6}'`

if [ "$sys" = 'disk' ];then
	if [ "$id" = 'usb' ];
		then
		echo "$line : USB $capacity $vendor $model"
	fi
fi


done;
}

devices | zenity --list --width=500 --height=300 --window-icon=question --title="Seleccione dispositivo" --text="<b>($( devices | grep -c dev)) dispositivo/s encontrados.</b>\nSi no encuentra su unidad de grabación, verifíquelo manualmente.\n "   --column="Ruta del dispositivo" 2> /dev/null
;;

#'--manual')
#zenity --entry --title="Custom device" --text='Specify device full path:' --entry-text='/dev/example'
#;;

'--empty')
zenity --error   --title="Error" --text="Dispositivo $2 está vacío.\nInserte un disco virgen o regrabable en la unidad e inténtelo nuevamente."
;;

'--used')
zenity --error   --title="Error" --text="Este disco ya fue utilizado.\nInserte un disco virgen o regrabable en la unidad e inténtelo nuevamente."
;;


#'--invalid')
#zenity --error --title="Error" --text="Unable to connect with $2 path device.\nVerify that device path is correct and try again."
#;;

'--invalid_file')
zenity --error   --title="Error" --text="El archivo de imágen es inválido, inténtelo nuevamente"
;;

'--nullpath')
zenity --error   --title="Error" --no-wrap --text="No ha seleccionado una ruta de dispositivo, inténtelo nuevamente."
;;

'--abort')
return 1
;;

'--aborted')
zenity --error   --title="Error" --no-wrap --text="Cancelado por el usuario. Intente luego."
;;

#'--rw')
#zenity --question --title="RW medium found" --no-wrap --text="Rewritable medium found, but it\'s already written and needs format to continue.\nDo you wan\'t to continue?\n\n<i>All data from current disk will be lost, and format will perfomed in fast mode.</i>"
#;;

'--speed_dvd')
min=$(( $(cat /tmp/log | grep -c "Descriptor#")-1))

(cat /tmp/log | grep "Write Speed" | sed 1d | sed 's/x1385=/X /g' | sed 's/Write Speed \#//g' | sed 's/\://g') | while read LINE ;do

id=$(echo $LINE | awk '{print $1}')
speed=$(echo $LINE | awk '{print $2}')
rate=$(echo $LINE | awk '{print $3}')

if [ $id = $min ]; 
	then
		echo "TRUE";echo "$speed"; echo "$rate"
	else
		echo "FALSE";echo "$speed"; echo "$rate"
fi


done | zenity --list   --radiolist --width=500 --height=300 --column=' ' --column="Velocidad" --title="Seleccione velocidad de escritura" --text="Velocidades disponibles para el medio actual : $dev.\nNOTA: Seleccione velocidades bajas para disminuir las probabilidades de falla." --column="Tasa (KB/s)" 2> /dev/null
;;


'--speed_cd')
max=`cdrdao drive-info --device $dev | grep 'Maximum writing' | rev | cut -d\  -f 2 | rev`
limit=$(printf %0.f `echo $max/150 | bc -l`)
	
case $type in

cdrw)
	
	(
	
	for i in `seq $limit -2 2`; do
	
	echo "FALSE"; echo "$i"X; echo $(($i*150))
	
	done 
	
	echo "TRUE"; echo "1X"; echo "150" 
	
	)| zenity --list    --radiolist --width=500 --height=300 --column=' ' --column="Velocidad" --title="Seleccione velocidad de escritura" --text="Velocidades disponibles para el medio actual : $dev.\nNOTA: Seleccione velocidades bajas para disminuir las probabilidades de falla." --column="Tasa (KB/s)" 2> /dev/null
;;

cd)

	(
	
	for i in `seq $limit -8 8`; do
	
	echo "FALSE"; echo "$i"X; echo $(($i*150))
	
	done 
	
	echo "TRUE"; echo "1X"; echo "150" 
	
	)| zenity --list    --radiolist --width=500 --height=300 --column=' ' --column="Velocidad" --title="Seleccione velocidad de escritura" --text="Velocidades disponibles para el medio actual : $dev.\nNOTA: Seleccione velocidades bajas para disminuir las probabilidades de falla." --column="Tasa (KB/s)" 2> /dev/null
;;



esac
;;

#'--root')
#zenity --password --title="Administrative access"
#;;

#'--root_err')
#zenity --error --no-wrap --title='Error' --text="Administrative password is invalid. Contact your system administrator and retry again."
#;;

#'--mount_err2')
#zenity --question --title="La unidad se encuentra montada" --no-wrap --text="$2 hace referencia a los siguientes puntos de montaje:\n\n$(lsblk $2 -o NAME,MOUNTPOINT)\n\nSe necesita desmontar la unidad para miniminizar fallas.\n¿Desea desmontar las unidades desde aquí y continuar?\n\n<i>NOTA: Esta operación requiere privilegios de administrador.</i>"
#;;

'--mount_err')
zenity --error    --title="La unidad se encuentra montada" --no-wrap --text="$2 hace referencia a los siguientes puntos de montaje:\n\n$(lsblk $2 -o NAME,MOUNTPOINT)\n\nSe necesita desmontar la unidad para minimizar fallas.\nHazlo manualmente tipeando en una terminal: \n\n<i>sudo umount \"ruta de montaje\"</i>\n\nPor favor, desmonte las unidades mostradas e intente nuevamente."
;;

'--notyet')
zenity --error    --no-wrap --title='No soportado' --text="CD no es soportado en este momento. Solamente DVD/BD.\nEsta característica estará disponible en futuras versiones.\n\nInserte un disco DVD/BD virgen e inténtelo de nuevo." 

;;

#'--burn_confirmation')
#text="Confirm the operation to start the writing process:\n\nDevice: $dev \nImage path: $file \nWriting speed: $speed\n\nClick yes to begin.\n\n<i>NOTE: Process cannot be stopped until be finished. Be sure before continue.</i>"
#zenity --question --no-wrap --title='Confirmation' --text="$text"
#;;

'--usb_confirmation')
zenity --question    --no-wrap --title='Confirmar' --text="Esta operación destruirá todos los datos presentes en $2.\nLa acción es irreversible, ¿Desea continuar?\n\nNOTA: Este proceso mostrará un progreso inicial y luego correrá en segundo plano.\nPor ningún motivo extraiga su pendrive, cuando la operación esté finalizada será avisado."
;;

#'--compatibility') 
#zenity --question --no-wrap --title="Compatibility" --text="Only open standard formats ISO/UDF are allowed to be burned directly over media without any loss of data.\n\nPropietary or non-standard formats, needs a conversion step to ISO standard format to be recognized.\n\nAny conversion from non-standard formats are not exactly, because data structures are only know by format owners.\nIn most cases, ~5% sizes differences after conversion are not relationated with damaged/loss data and information is safe.\nBut, sometimes differences are considerable and data could be corrupt/lost like images built from multisector disks.\n\nConversion will be perfomed, then you can evaluate if integrity is acceptable and proceed burning.\nDo you want to continue?"
#;;

'--file')
zenity --file-selection    --title="Seleccione imágen de disco" --text="available" --filename=$HOME/ \
--file-filter="Todas las imágenes soportadas | *.iso *.ISO *.udf *.UDF" \
--file-filter="Estándar ISO (*.iso)| *.iso *.ISO" \
--file-filter="Estándar UDF (*.udf) | *.udf *.UDF" \
;;

'--finished_usb')
zenity --info    --no-wrap --title="Finalizado" --text="Proceso completado. Se recomienda no extraer el pendrive durante aproximadamente 5 minutos.\nEl copiado asincrónico puede estar aún activo a pesar de su señal de finalización.\n\n<i>NOTA: No extraiga su pendrive directamente, utilice la opción expulsar para evitar fallas.</i>"
;;

'--missing')
	zenity --error    --no-wrap --title="Error" --text="Los siguientes paquetes no han sido encontrados en su sistema:\n\n$2\n\nPor favor instálelos e intente nuevamente."
;;

esac

}

check(){
case $1 in	

--dvdrw)
cat /tmp/log | grep "Mounted" | grep -c RW
;;

--dvdblank)
cat /tmp/log | grep "Disc status" | cut -d: -f2 | sed 's/ //g'
;;

--packages)

rm '/tmp/unmet'

if [ `which zenity` ]; 
	then
		for i in cdrdao growisofs pv; do
		
		if [ `which "$i"` ]; then
			if [ "$i" = 'growisofs' ];then echo "dvd+rw-tools : Found" >> /tmp/unmet ;else	echo "$i" : Found >> /tmp/unmet;fi
			
			else
			
			if [ "$i" = 'growisofs' ];then echo "dvd+rw-tools : Found"  >> /tmp/unmet ;err=2 ;else	echo "$i" : Not found >> /tmp/unmet;err=2;fi
		fi
		
		done
		
		if [ "$err" = 2 ];
		then
			
			dialog --missing "$(cat /tmp/unmet)"
			exit 2
		fi
	else
		xterm -e "echo Zenity no está instalado en su sistema, instálelo e intente nuevamente.;read"
		exit 2
fi
;;

esac
}

ask_device(){
dev=`dialog --mainlist` || return 1 

if [ -z "$dev" ]; then zenity --error --title="Error" --text="No ha seleccionado una unidad, vuelva a intentarlo.";i=2;return 1; else

dev=`echo $dev | awk '{print $1}'`

(dvd+rw-mediainfo $dev > /tmp/log) 2> /dev/null

case $? in

	0)  
		if [ `cat /tmp/log | grep "Disc status" | cut -d: -f2 | sed 's/ //g'` = 'blank' ]
			then
				type='dvd'
			
			else 
				if [ `cat /tmp/log | grep "Mounted" | grep -c RW` = 1 ]
					then
					type='dvdrw'
					
					else
					dialog --used && i=2;return 1
				fi
		fi
			
	;;
	
	252) 
	
	dialog --notyet && i=2;return 1
	;;
	
	251) 
	dialog --empty "$dev" && i=2;return 1
	;;
	
	150)
	type='usb'	
	disconnect=`lsblk $dev -o MOUNTPOINT | grep "/"`
	if [ -z "$disconnect" ]
	then
		echo "$dev is ready"
	else
		echo "$dev is not ready. You need umount device before use it"
		dialog --mount_err "$dev" && i=2;return 1
		
		
	fi
	;;
	
			
esac

fi

}

ask_file(){
file=`dialog --file` || return 1

if [ -f "$file" -a -r "$file" -a -s "$file" ] 
	then
	
		case `echo $file | rev | cut -d. -f 1 | rev | sed 's/\(.*\)/\L\1/'` in
							
			iso|udf)
			return 0
			;;
			
			
			*) 
			dialog --invalid_file && return 1
			;;
		
		esac 
	else
	
	dialog --invalid_file && return 1
fi


}

ask_speed(){

case $type in

dvd|dvdrw)
speed=`dialog --speed_dvd` || return 1
;;

cd|cdrw)
speed=`dialog --speed_cd` || return 1
;;

usb)
return 0
;;

esac
speed=$(echo $speed | sed 's/X//g')

}

burn(){

case $type in

dvd)
(( growisofs -dvd-compat -use-the-force-luke -Z "$dev"="$file" -speed="$speed"  ) | while read line ;do echo $line | awk '{print $2}' | sed 's/(//g' | sed 's/)//g' ;done) | zenity --progress --width=500 --height=200 --no-cancel --auto-close --percentage=0 --text="Grabando, por favor espere..." --title="Grabando imágen de disco"

;;

dvdrw)
dvd+rw-format "$dev" | awk '{ print $1; fflush() }' | zenity --progress --width=500 --height=200 --no-cancel --auto-close --percentage=0 --text="Formateando, por favor espere..." --title="Preparando medio regrabable RW"

(( growisofs -dvd-compat -use-the-force-luke -Z "$dev"="$file" -speed="$speed"  ) | while read line ;do echo $line | awk '{print $2}' | sed 's/(//g' | sed 's/)//g' ;done) | zenity --progress --width=500 --height=200 --no-cancel --auto-close --percentage=0 --text="Grabando, por favor espere..." --title="Grabando imágen de disco"

;;

usb)
notify(){
notify-send "Trabajando en segundo plano..." "Cuando el proceso haya alcanzado el 100% será avisado\nNo extraiga su pendrive durante el proceso."
}

dialog --usb_confirmation $dev && cont='yes' #|| ( i=3;return 1 )

if [ "$cont" = "yes" ]
	then
		notify
		echo "working"
		(pv -n "$file" | dd of="$dev" bs=4M ) 2>&1 | zenity --progress --width=500 --height=200 --no-cancel --auto-close --percentage=0 --title="Escribiendo medio USB" --text="Copiando, por favor espere.. \nNo extraiga su pendrive durante el proceso, podrías dañar los datos."
		dialog --finished_usb
		return 0
	else
		i=3
		return 1
fi

#dd bs=4M if="$file" of="$dev" && sync | zenity --progress --no-cancel --auto-close --pulsate
#(pv -n "$file" | dd of="$dev" bs=4M ) 2>&1 | zenity --progress --width=500 --height=200 --no-cancel --auto-close --percentage=0 --title="Writing USB" --text="Copying, please wait.. \nDon\'t extract your USB during process, you can damage it"

;;

esac

}




main(){

echo "Process step $i"

case $1 in 

1) ask_device && let i++ || let i--
;; 

2) ask_file && let i++ || let i--
;;

3) ask_speed && let i++ || let i--
;;

4) burn && exit 0 || let i--
;;

0) exit 1 #aborted

;;

*) exit 0
;;

esac

main $i


}


check --packages

i=1 
main 1


